home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / viewwrld / viewwrld.lha / viewworld / gr / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-21  |  9.6 KB  |  343 lines

  1. /* $Id: print.c,v 2.3 89/09/20 17:01:46 mbp Exp $
  2.  *
  3.  * print.c: procedures for creating and using printer window
  4.  */
  5.  
  6. /************************************************************************
  7.  *        Copyright (C) 1989 by Mark B. Phillips                  *
  8.  *                                     *
  9.  * Permission to use, copy, modify, and distribute this software and    *
  10.  * its documentation for any purpose and without fee is hereby granted, *
  11.  * provided that the above copyright notice appear in all copies and    *
  12.  * that both that copyright notice and this permission notice appear in *
  13.  * supporting documentation, and that the name of Mark B. Phillips or   *
  14.  * the University of Maryland not be used in advertising or publicity   *
  15.  * pertaining to distribution of the software without specific, written *
  16.  * prior permission.  This software is provided "as is" without express *
  17.  * or implied warranty.                                                 *
  18.  ************************************************************************/
  19.  
  20. #include <stdio.h>
  21. #include "gr.h"
  22. #include "internal.h"
  23.  
  24. /* This max caption length assumes a point size of 16: */
  25. #define MAX_CAPTION_LENGTH 129
  26. #define FILENAME_DISPLAY_LENGTH 30
  27. #define FILENAME_STORED_LENGTH 256
  28. #define LABEL_DISPLAY_LENGTH 35
  29. /* Max label length is 26 less than max caption length, because time */
  30. /* string is 26 chars: */
  31. #define LABEL_STORED_LENGTH (MAX_CAPTION_LENGTH-26)
  32. #define PS_MESSAGE_LENGTH 37
  33.  
  34. Frame        GR_ps_frame = NULL;
  35. Panel        GR_ps_panel = NULL;
  36. static Panel_item    ps_printer_button, ps_file_button, ps_done_button;
  37. static Panel_item    ps_filename_text, ps_label_text, ps_message;
  38. static Panel_item    ps_time_cycle;
  39.  
  40. static int    ps_file_button_proc(), ps_printer_button_proc(), ps_done();
  41.  
  42. char *GR_logo=NULL;
  43.  
  44. /*-----------------------------------------------------------------------
  45.  * Function:    GR_show_ps_frame
  46.  * Description:    Display the PostScript frame
  47.  * Args:    (none)
  48.  */
  49. int
  50. GR_show_ps_frame()
  51. {
  52.   /* If we haven't created the ps frame yet, do so now */
  53.   if (GR_ps_frame == NULL)
  54.     initialize_ps_frame();
  55.  
  56.   /* Clear any message currently in the message area */
  57.   show_ps_message("");
  58.  
  59.   /* Now make it visible */
  60.   window_set(GR_ps_frame, WIN_SHOW, TRUE, 0);
  61. }
  62.  
  63. /*-----------------------------------------------------------------------
  64.  * Function:    initialize_ps_frame
  65.  * Description:    Initialize the PostScript frame
  66.  * Args:    (none)
  67.  */
  68. static int
  69. initialize_ps_frame()
  70. {
  71.   GR_ps_frame =
  72.     window_create(GR_base_frame, FRAME,
  73.           WIN_X, 457,
  74.           WIN_Y, 0,
  75.           FRAME_LABEL, "PostScript",
  76.           FRAME_SHOW_LABEL, TRUE,
  77.           0);
  78.   if (GR_ps_frame == NULL) {
  79.     GR_error("I can't create any more windows !");
  80.     return(1);
  81.   }
  82.   
  83.   GR_ps_panel =
  84.     window_create(GR_ps_frame, PANEL,
  85.           WIN_X, 0,
  86.           WIN_Y, 0,
  87.           WIN_WIDTH, 352,
  88.           WIN_HEIGHT, 142,
  89.           0);
  90.   if (GR_ps_panel == NULL) {
  91.     GR_error("I can't create any more windows !");
  92.     return(1);
  93.   }
  94.   
  95.   ps_printer_button =
  96.     panel_create_item(GR_ps_panel, PANEL_BUTTON, 
  97.               PANEL_ITEM_X, 10,
  98.               PANEL_ITEM_Y, 12,
  99.               PANEL_LABEL_IMAGE,
  100.               panel_button_image(GR_ps_panel, "Printer", 8, 0),
  101.               PANEL_NOTIFY_PROC, ps_printer_button_proc,
  102.               0);
  103.   
  104.   ps_file_button =
  105.     panel_create_item(GR_ps_panel, PANEL_BUTTON, 
  106.               PANEL_ITEM_X, 10,
  107.               PANEL_ITEM_Y, 44,
  108.               PANEL_LABEL_IMAGE,
  109.               panel_button_image(GR_ps_panel, "File", 5, 0),
  110.               PANEL_NOTIFY_PROC, ps_file_button_proc,
  111.               0);
  112.  
  113.   ps_label_text =
  114.     panel_create_item(GR_ps_panel, PANEL_TEXT, 
  115.               PANEL_ITEM_X, 10,
  116.               PANEL_ITEM_Y, 72,
  117.               PANEL_VALUE_DISPLAY_LENGTH, LABEL_DISPLAY_LENGTH,
  118.               PANEL_VALUE_STORED_LENGTH, LABEL_STORED_LENGTH,
  119.               PANEL_LABEL_STRING, "Label:",
  120.               0);
  121.   
  122.   ps_filename_text =
  123.     panel_create_item(GR_ps_panel, PANEL_TEXT, 
  124.               PANEL_ITEM_X, 70,
  125.               PANEL_ITEM_Y, 47,
  126.               PANEL_VALUE_DISPLAY_LENGTH, FILENAME_DISPLAY_LENGTH,
  127.               PANEL_VALUE_STORED_LENGTH, FILENAME_STORED_LENGTH,
  128.               PANEL_LABEL_STRING, "Filename:",
  129.               0);
  130.  
  131.   ps_time_cycle = 
  132.     panel_create_item(GR_ps_panel, PANEL_CYCLE,
  133.               PANEL_ITEM_X, 10,
  134.               PANEL_ITEM_Y, 95,
  135.               PANEL_LABEL_STRING, "Time on Picture",
  136.               PANEL_CHOICE_STRINGS,
  137.                 "No",  /* panel_value = 0 */
  138.                 "Yes", /* panel_value = 1 */
  139.                 0,
  140.               PANEL_VALUE, 1,
  141.               0);
  142.   
  143.   ps_done_button =
  144.     panel_create_item(GR_ps_panel, PANEL_BUTTON, 
  145.               PANEL_ITEM_X, 258,
  146.               PANEL_ITEM_Y, 9,
  147.               PANEL_LABEL_IMAGE,
  148.               panel_button_image(GR_ps_panel, "Done", 7, 0),
  149.               PANEL_NOTIFY_PROC, ps_done,
  150.               0);
  151.  
  152.   ps_message =
  153.     panel_create_item(GR_ps_panel, PANEL_MESSAGE,
  154.               PANEL_ITEM_X, 10,
  155.               PANEL_ITEM_Y, 118,
  156.               PANEL_LABEL_STRING, "Printer Error Message Here",
  157.               PANEL_LABEL_FONT, GR_bold_font,
  158.               0);
  159.   
  160.   window_fit(GR_ps_frame);
  161.   GR_register_interposer(GR_ps_frame);
  162. }
  163.  
  164. /*-----------------------------------------------------------------------
  165.  * Function:    ps_done
  166.  * Description:    close the PostScript window
  167.  */
  168. static int
  169. ps_done()
  170. {
  171.   window_set(GR_ps_frame, WIN_SHOW, FALSE, 0);
  172. }
  173.  
  174. /*-----------------------------------------------------------------------
  175.  * Function:    ps_file_button_proc
  176.  * Description:    notify proc for "File" button
  177.  */
  178. static int
  179. ps_file_button_proc()
  180. {
  181.   char *filename;
  182.   char msg[256];
  183.  
  184.   /* Get the file name */
  185.   filename = (char *)panel_get_value(ps_filename_text);
  186.  
  187.   /* Confirm overwrite, if necessary */
  188.   if (GR_file_openable(filename, "r")) {
  189.     if (!gr_user_confirm("Overwite existing file?")) {
  190.       show_ps_message("File not written");
  191.       return(0);
  192.     }
  193.   }
  194.  
  195.   /* Check for write permission */
  196.   if (!GR_file_openable(filename, "w")) {
  197.     sprintf(msg,"I can't write to file \"%s\" !", filename);
  198.     show_ps_error(msg);
  199.     return(0);
  200.   }
  201.  
  202.   /* Write the file and signal success or failure */
  203.   if (write_postscript_file(filename) == 0) {
  204.     sprintf(msg, "Wrote \"%s\".", filename);
  205.     show_ps_message(msg);
  206.   }
  207.   else {
  208.     sprintf(msg, "Couldn't write \"%s\".", filename);
  209.     show_ps_error(msg);
  210.   }
  211.  
  212.   return(0);
  213. }
  214.  
  215. /*-----------------------------------------------------------------------
  216.  * Function:    ps_printer_button_proc
  217.  * Description:    send PostScript to printer
  218.  * Args:    (none)
  219.  */
  220. static int
  221. ps_printer_button_proc()
  222. {
  223.   int r;
  224.   char *mktemp(), *getenv();
  225.   static char template[] = "/tmp/grXXXXXX";
  226.   char filename[sizeof(template)+1];
  227.   char command[256], *spool_command;
  228.  
  229.   /* Make sure we are able to print PostScript files */
  230.   /*   First check for presence of GR_SPOOL environment variable */
  231.   spool_command = getenv("GR_SPOOL");
  232.   if (spool_command == NULL) {
  233.     /* Then check for default spool command given at compile time */
  234.     if (strlen(DEFAULT_SPOOL_COMMAND) > 0) {
  235.       spool_command = DEFAULT_SPOOL_COMMAND;
  236.     }
  237.     else {
  238.       /* We can't print! */
  239.       show_ps_error("Don't know how to print PostScript !");
  240.       return(1);
  241.     }
  242.   }
  243.  
  244.   /* Get name for temporary file for PostScript output */
  245.   strcpy(filename, template);
  246.   mktemp(filename);
  247.   if (!GR_file_openable(filename, "w")) {
  248.     show_ps_error("Can't write temporary file !");
  249.   }
  250.   else {
  251.  
  252.     /* Write the file */
  253.     if (write_postscript_file(filename) != 0) {
  254.       show_ps_error("Error in writing temporary file !");
  255.     }
  256.     
  257.     else {
  258.  
  259.       /* Send the file to the printer */
  260.       sprintf(command, "%s %s", spool_command, filename);
  261.       if (system(command) == 0)
  262.     show_ps_message("PostScript image sent to printer");
  263.       else {
  264.     show_ps_error("Error in sending PostScript to printer !");
  265.     }
  266.     
  267.     /* Now delete the temporary file */
  268.     sprintf(command,"/bin/rm -f %s", filename);
  269.     system(command);
  270.  
  271.     }
  272.   }
  273. }
  274.  
  275. /*-----------------------------------------------------------------------
  276.  * Function:    write_postscript_file
  277.  * Description:    write PostScript to a file
  278.  * Args  IN:    filename: name of file to write to
  279.  * Notes:    This calls the value of GR_redraw_proc to cause the
  280.  *        canvas to be redrawn in "postscript" mode.  This procedure
  281.  *        should have been specified in the initial call to
  282.  *        gr_print_button.
  283.  */
  284. static int
  285. write_postscript_file(filename)
  286.      char *filename;
  287. {
  288.   int r;
  289.   char *label, *timeptr, timestr[30];
  290.   long clock;
  291.   extern char *ctime();
  292.  
  293.   /* Get label */
  294.   label = (char*)panel_get_value(ps_label_text);
  295.   if (strlen(label) == 0) label=NULL;
  296.  
  297.   /* Get time string, maybe */
  298.   if (panel_get_value(ps_time_cycle)) {
  299.     /* Time cycle is "Yes", so do use time string */
  300.     clock = time(0);
  301.     strcpy(timestr, ctime(&clock));    /* (26 chars with final newline) */
  302.     timestr[strlen(timestr)-1] = '\0'; /* (this takes out final newline) */
  303.     timeptr = timestr;
  304.   }
  305.   else
  306.     timeptr = NULL;
  307.     
  308.   if (gr_postscript_begin(filename, GR_logo, label, timeptr) != 0) return(1);
  309.   if (GR_redraw_proc == NULL) return(1);
  310.   r = (*GR_redraw_proc)();
  311.   r |= gr_postscript_end();
  312.   return(r);
  313. }
  314.  
  315. /*-----------------------------------------------------------------------
  316.  * Function:    show_ps_message
  317.  * Description:    display a string in the message area of the ps panel
  318.  * Args  IN:    s: the string to be displayed
  319.  * Notes:    Only the first PS_MESSAGE_LENGTH chars are displayed
  320.  */
  321. static int
  322. show_ps_message(s)
  323. char *s;
  324. {
  325.   return(GR_show_message(ps_message, s, PS_MESSAGE_LENGTH));
  326. }
  327.  
  328. /*-----------------------------------------------------------------------
  329.  * Function:    show_ps_error
  330.  * Description:    display a string in the message area of the ps panel
  331.  *          and beep the bell
  332.  * Args  IN:    s: the string to be displayed
  333.  * Notes:    Only the first PS_MESSAGE_LENGTH chars are displayed
  334.  */
  335. static int
  336. show_ps_error(s)
  337. char *s;
  338. {
  339.   window_bell(GR_ps_panel);
  340.   window_bell(GR_ps_panel);
  341.   return(GR_show_message(ps_message, s, PS_MESSAGE_LENGTH));
  342. }
  343.